package com.geek.water.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.geek.water.constant.InvoiceConstants;
import com.geek.water.dto.InvoiceQueryDTO;
import com.geek.water.dto.InvoiceRequestDTO;
import com.geek.water.dto.InvoiceResponseDTO;
import com.geek.water.service.NuonuoInvoiceService;
import lombok.extern.slf4j.Slf4j;
import nuonuo.open.sdk.NNOpenSDK;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

/**
 * 诺诺网发票服务实现
 */
@Service
@Slf4j
public class NuonuoInvoiceServiceImpl implements NuonuoInvoiceService {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public InvoiceResponseDTO applyInvoice(InvoiceRequestDTO requestDTO) {
        try {
            log.info("开始申请开具发票，订单号：{}", requestDTO.getBillcode());
            String content = buildInvoiceContent(requestDTO);
            log.info("构建的请求内容: {}", content);

            String senid = UUID.randomUUID().toString().replace("-", "");
            NNOpenSDK sdk = NNOpenSDK.getIntance();
            log.info("调用诺诺网SDK: url={}, appKey={}, method={}",
                    InvoiceConstants.TEST_URL,
                    InvoiceConstants.TEST_APP_KEY,
                    InvoiceConstants.APPLY_METHOD);

            String result = sdk.sendPostSyncRequest(
                    InvoiceConstants.TEST_URL,
                    senid,
                    InvoiceConstants.TEST_APP_KEY,
                    InvoiceConstants.TEST_APP_SECRET,
                    "",
                    InvoiceConstants.TEST_SALER_TAX_NUM,
                    InvoiceConstants.APPLY_METHOD,
                    content
            );

            log.info("诺诺网原始响应：{}", result);
            return parseResponse(result);
        } catch (Exception e) {
            log.error("申请开具发票失败", e);
            return createErrorResponse("申请开具发票失败：" + e.getMessage());
        }
    }

    @Override
    public InvoiceResponseDTO queryInvoice(InvoiceQueryDTO queryDTO) {
        try {
            log.info("开始查询发票，订单号：{}", queryDTO.getBillcode());
            String content = buildQueryContent(queryDTO);
            log.info("查询请求内容: {}", content);

            String senid = UUID.randomUUID().toString().replace("-", "");
            NNOpenSDK sdk = NNOpenSDK.getIntance();
            String result = sdk.sendPostSyncRequest(
                    InvoiceConstants.TEST_URL,
                    senid,
                    InvoiceConstants.TEST_APP_KEY,
                    InvoiceConstants.TEST_APP_SECRET,
                    "",
                    InvoiceConstants.TEST_SALER_TAX_NUM,
                    InvoiceConstants.QUERY_METHOD,
                    content
            );

            log.info("诺诺网查询响应：{}", result);
            return parseResponse(result);
        } catch (Exception e) {
            log.error("查询发票失败", e);
            return createErrorResponse("查询发票失败：" + e.getMessage());
        }
    }

    private String buildInvoiceContent(InvoiceRequestDTO requestDTO) {
        String detailsJson = buildInvoiceDetail(requestDTO.getInvoiceDetail());
        String invoiceDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return String.format(
                "{\"order\":{"
                        + "\"invoiceDetail\":[%s],"
                        + "\"buyerName\":\"%s\","
                        + "\"buyerAddress\":\"%s\","
                        + "\"buyerTaxNum\":\"%s\","
                        + "\"buyerPhone\":\"%s\","
                        + "\"email\":\"%s\","
                        + "\"invoiceType\":\"%s\","
                        + "\"invoiceLine\":\"%s\","
                        + "\"listFlag\":\"%s\","
                        + "\"pushMode\":\"%s\","
                        + "\"salerAccount\":\"%s\","
                        + "\"salerAddress\":\"%s\","
                        + "\"salerTel\":\"%s\","
                        + "\"salerTaxNum\":\"%s\","
                        + "\"orderNo\":\"%s\","
                        + "\"invoiceDate\":\"%s\","
                        + "\"clerk\":\"张三\","
                        + "\"checker\":\"张三\","
                        + "\"payee\":\"张三\","
                        + "\"payer\":\"张三\""
                        + "}}",
                detailsJson,
                requestDTO.getBuyerName(),
                requestDTO.getBuyerAddress(),
                requestDTO.getBuyerTaxNum(),
                requestDTO.getBuyerPhone(),
                requestDTO.getEmail(),
                InvoiceConstants.INVOICE_TYPE,
                InvoiceConstants.INVOICE_LINE,
                InvoiceConstants.LIST_FLAG,
                InvoiceConstants.PUSH_MODE,
                InvoiceConstants.TEST_SALER_ACCOUNT,
                InvoiceConstants.TEST_SALER_ADDRESS,
                InvoiceConstants.TEST_SALER_TEL,
                InvoiceConstants.TEST_SALER_TAX_NUM,
                requestDTO.getBillcode(),
                invoiceDate
        );
    }

    private String buildInvoiceDetail(List<InvoiceRequestDTO.InvoiceDetailDTO> details) {
        StringBuilder sb = new StringBuilder();
        for (InvoiceRequestDTO.InvoiceDetailDTO d : details) {
            sb.append("{")
                    .append("\"taxRate\":\"").append(d.getTaxRate()).append("\",")
                    .append("\"invoiceLineProperty\":\"").append(d.getInvoiceLineProperty()).append("\",")
                    .append("\"selfCode\":\"").append(d.getSelfCode()).append("\",")
                    .append("\"listName\":\"").append(d.getListName()).append("\",")
                    .append("\"specType\":\"").append(d.getSpecType()).append("\",")
                    .append("\"goodsName\":\"").append(d.getGoodsName()).append("\",")
                    .append("\"goodsCode\":\"").append(d.getGoodsCode()).append("\",")
                    .append("\"taxExcludedAmount\":\"").append(d.getTaxExcludedAmount()).append("\",")
                    .append("\"withTaxFlag\":\"").append(d.getWithTaxFlag()).append("\",")
                    .append("\"num\":\"").append(d.getNum()).append("\",")
                    .append("\"tax\":\"").append(d.getTax()).append("\",")
                    .append("\"unit\":\"").append(d.getUnit()).append("\",")
                    .append("\"deduction\":\"").append(d.getDeduction()).append("\",")
                    .append("\"price\":\"").append(d.getPrice()).append("\"")
                    .append("},");
        }
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }
        return sb.toString();
    }

    private String buildQueryContent(InvoiceQueryDTO queryDTO) {
        StringBuilder content = new StringBuilder("{");
        content.append("\"isOfferInvoiceDetail\":\"1\",");
        content.append("\"orderNos\":\"").append(queryDTO.getBillcode()).append("\"");
        if (queryDTO.getInvoiceCode() != null && !queryDTO.getInvoiceCode().isEmpty()
                && queryDTO.getInvoiceNumber() != null && !queryDTO.getInvoiceNumber().isEmpty()) {
            content.append(",\"serialNos\":\"")
                    .append(queryDTO.getInvoiceCode())
                    .append(",")
                    .append(queryDTO.getInvoiceNumber())
                    .append("\"");
        }
        content.append("}");
        return content.toString();
    }

    private InvoiceResponseDTO parseResponse(String responseBody) {
        try {
            log.debug("解析诺诺网响应: {}", responseBody);
            JsonNode rootNode = objectMapper.readTree(responseBody);
            InvoiceResponseDTO response = new InvoiceResponseDTO();
            response.setCode(rootNode.path("code").asText());
            response.setMessage(rootNode.path("describe").asText());

            JsonNode resultNode = rootNode.path("result");
            if (resultNode.isMissingNode()) {
                return response;
            }

            InvoiceResponseDTO.InvoiceDataDTO data = new InvoiceResponseDTO.InvoiceDataDTO();
            if (resultNode.isArray() && resultNode.size() > 0) {
                JsonNode node = resultNode.get(0);
                data.setInvoiceCode(node.path("invoiceCode").asText());
                data.setInvoiceNumber(node.path("invoiceNo").asText());
                data.setCheckCode(node.path("checkCode").asText());
                data.setMachineCode(node.path("machineCode").asText());
                data.setInvoiceDate(node.path("invoiceDate").asText());
                data.setStatus(node.path("statusMsg").asText());
                data.setImgUrls(node.path("imgUrls").asText());
                data.setTotalAmount(node.path("orderAmount").asText());
                data.setTaxAmount(node.path("taxAmount").asText());
            } else if (resultNode.isObject()) {
                String serials = resultNode.path("invoiceSerialNum").asText("");
                String[] parts = serials.split(",");
                data.setInvoiceCode(parts.length > 0 ? parts[0] : "");
                data.setInvoiceNumber(parts.length > 1 ? parts[1] : "");
                // 沙箱环境下没有金额返回，默认置零，避免空指针
                data.setTotalAmount("0");
                data.setTaxAmount("0");
            }
            response.setData(data);
            return response;
        } catch (Exception e) {
            log.error("解析响应失败，原始响应: {}", responseBody, e);
            return createErrorResponse("解析响应失败：" + e.getMessage());
        }
    }

    private InvoiceResponseDTO createErrorResponse(String message) {
        InvoiceResponseDTO response = new InvoiceResponseDTO();
        response.setCode("ERROR");
        response.setMessage(message);
        return response;
    }
}

